/*Funcion para obtener la cantidad minima de una medicina en especifico*/
CREATE OR REPLACE 
FUNCTION CantidadMinimaMedClinica (idMedicina in  Number)
RETURN NUMBER 
IS cantMin NUMBER;
BEGIN 
select m.CANTMINIMAINVENT into cantMin
from medicina m
where m.id = idMedicina;
RETURN cantMin;
END;

------------------------------------------------------------------------------------------------------
/*Funcion generar pedido a partir de falta de alguna medicina*/
CREATE OR REPLACE 
PROCEDURE pedidofacturamedicina (idMedicina in NUMBER, rifClinica in varchar2, fechaVencimiento IN DATE) IS 
cantPedido NUMBER(20);
costoMed FLOAT(40);
costototalpedido FLOAT(40);
descripcion VARCHAR2(100);
nombMedicina VARCHAR2(30);
idFactura NUMBER(20);
nomClinica varchar2(30);
BEGIN
	DBMS_OUTPUT.PUT_LINE('Cantidad Min: ');
	cantPedido := 1000;
	--Buscando el costo de la medicina 
	select m.costo into costoMed
	from medicina m
	where m.id = idMedicina;
	-- Buscando el nombre de la medicina para la descripcion
	select m.nombrecomercial into nombMedicina from medicina m where m.id = idMedicina;

	--Buscando el nombre de la clinica la cual hace el pedido
	select c.nombre into nomClinica from clinica c where c.rif = rifClinica;

	costototalpedido := cantPedido * costoMed;

	descripcion := 'Pedido para el abastecimiento de la medicina: '||nombMedicina||'.';

	DBMS_OUTPUT.PUT_LINE(descripcion);

	insertarfactura(costototalpedido,descripcion);

	select MAX(f.id) into idFactura from factura f;

	DBMS_OUTPUT.PUT_LINE('Se ha efectuado un pedido para abastecer la medicina: '||nombMedicina||' para la clinica: '||nomClinica);

	insertarPedido(costototalpedido, idMedicina , rifClinica, idFactura,cantPedido);
	
	abastecermedicinaclinica(rifClinica ,idMedicina ,cantPedido, fechaVencimiento);

END;
----------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
PROCEDURE insertarFactura
(costo IN FLOAT ,descripcion IN VARCHAR2 )
AS 
BEGIN   
	INSERT INTO FACTURA VALUES (IDFACTURA.nextval,sysdate,costo,descripcion);
	commit;
END;
----------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
PROCEDURE insertarpedido 
(costototal IN FLOAT ,idMedicina IN NUMBER ,rifClinica IN VARCHAR2 ,idFactura IN NUMBER ,cantPedido IN NUMBER)
AS 
BEGIN   
	INSERT INTO PEDIDO VALUES (IDPEDIDO.nextval,sysdate,costototal,cantPedido,idMedicina,null,null,rifClinica,idFactura);
	commit; 
END;
----------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
FUNCTION verificarExistenciaMedInv
(rifClinicas IN VARCHAR2 ,
idMedicinas IN VARCHAR2, fechaVec DATE ) RETURN NUMBER
AS 
v_inventario         INVENTARIOMEDCLINICA%ROWTYPE;
fechaVarchar varchar2(49);
type inv_tipoarray is varray(1000) of INVENTARIOMEDCLINICA%rowtype;
array_inv inv_tipoarray := inv_tipoarray() ;
indx   number := 1;
fechaAux DATE;
cantidadDatos number (20);
BEGIN

	fechaVarchar := to_char(fechaVec,'dd/mm/yyyy');
	fechaAux := fechaVec;

	FOR v_inventario IN
	(SELECT i.rifClinica, i.idMedicina,i.cantidad, to_char(i.fechaVencimiento,'dd/mm/yyyy') fechaVencimiento FROM INVENTARIOMEDCLINICA i WHERE
	i.rifClinica = rifClinicas AND i.idMedicina = idMedicinas AND i.fechaVencimiento = fechaVarchar ) LOOP

		fechaAux := to_date(v_inventario.fechaVencimiento,'dd/mm/yyyy');
		
		if indx < array_inv.limit then
		   array_inv.extend;
		   array_inv(array_inv.last).rifClinica := v_inventario.rifClinica;
		   array_inv(array_inv.last).idMedicina := v_inventario.idMedicina;
		   array_inv(array_inv.last).cantidad := v_inventario.cantidad;
		   array_inv(array_inv.last).fechaVencimiento := fechaAux;		
		   indx := indx +1;
		end if;

		DBMS_OUTPUT.PUT_LINE('RIF clinica:  '    || 
		array_inv(array_inv.last).rifClinica);
		DBMS_OUTPUT.PUT_LINE('idMedicina '   || 
		array_inv(array_inv.last).idMedicina);
		DBMS_OUTPUT.PUT_LINE('cantidad de medicina '   || 
		array_inv(array_inv.last).cantidad );
		DBMS_OUTPUT.PUT_LINE('fecha vence '   || 
		array_inv(array_inv.last).fechaVencimiento);

	END LOOP;
	cantidadDatos := indx -1;
	--DBMS_OUTPUT.PUT_LINE('Cantidad: '   || cantidadDatos);
	RETURN cantidadDatos;

END;
----------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
PROCEDURE abastecermedicinaclinica
(rifClinica IN VARCHAR2 ,
idMedicina IN VARCHAR2 ,
cantidadMed IN NUMBER, fechaVec DATE)
AS 
cantidadDatos number (20);
fechaVarchar varchar2(20);
BEGIN

	fechaVarchar := to_char(fechaVec,'dd/mm/yyyy');
	cantidadDatos := verificarExistenciaMedInv(rifClinica ,idMedicina, fechaVec);

	IF cantidadDatos = 0 THEN
		INSERT INTO INVENTARIOMEDCLINICA VALUES (rifClinica,idMedicina,cantidadMed,sysdate,sysdate,null,fechaVec);
	ELSE
		UPDATE INVENTARIOMEDCLINICA I SET I.cantidad = cantidadMed WHERE I.rifClinica = rifClinica AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
	END IF;

END;
---------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE
PROCEDURE actualInventarioAfterConsumo
(rifClinica IN VARCHAR2 ,idMedicina IN VARCHAR2 ,cantidadConsumo NUMBER) 
AS
v_inventario         INVENTARIOMEDCLINICA%ROWTYPE;
type inv_tipoarray is varray(1000) of INVENTARIOMEDCLINICA%rowtype;
array_inv inv_tipoarray := inv_tipoarray();
indx   number := 1;
cantidadExistencias NUMBER := 0;
cantidadMedRecord NUMBER := 0;
transConfirm NUMBER := 0;
fechaVarchar varchar2(49);
fechaAux DATE;
cantNueva NUMBER := 0;
cantExcedente NUMBER :=0;
cantConsumoAux NUMBER :=0;
BEGIN 
	cantConsumoAux := cantidadConsumo;
	/*LOOP PARA BUSCAR LAS EXISTENCIAS DE ESA MEDICINA*/
	FOR v_inventario IN
	(SELECT i.rifClinica, i.idMedicina,i.cantidad,to_char(i.fechaVencimiento,'dd/mm/yyyy') fechaVencimiento FROM INVENTARIOMEDCLINICA i WHERE
	i.rifClinica = rifClinica AND i.idMedicina = idMedicina AND I.fechaEgreso is null ORDER BY i.fechaVencimiento ASC) LOOP

		fechaVarchar := v_inventario.fechaVencimiento;
		fechaAux := to_date(v_inventario.fechaVencimiento,'dd/mm/yyyy');
		
		if indx < array_inv.limit then
		   array_inv.extend;
		   array_inv(array_inv.last).rifClinica := v_inventario.rifClinica;
		   array_inv(array_inv.last).idMedicina := v_inventario.idMedicina;
		   array_inv(array_inv.last).cantidad := v_inventario.cantidad;
		   array_inv(array_inv.last).fechaVencimiento := fechaAux;	
		   indx := indx +1;
		end if;

		DBMS_OUTPUT.PUT_LINE('RIF clinica:  '    || 
		array_inv(array_inv.last).rifClinica);
		DBMS_OUTPUT.PUT_LINE('idMedicina '   || 
		array_inv(array_inv.last).idMedicina);
		DBMS_OUTPUT.PUT_LINE('cantidad de medicina '   || 
		array_inv(array_inv.last).cantidad );
	END LOOP; 
	cantidadExistencias := array_inv.COUNT;
	
	/*LOOP que actualiza el inventario segun el consumo*/
	FOR I in 1..array_inv.COUNT LOOP
		fechaVarchar := to_char(array_inv(I).fechaVencimiento,'dd/mm/yyyy');
		
		IF array_inv(I).cantidad >  cantConsumoAux THEN
			cantNueva := array_inv(I).cantidad - cantConsumoAux;		
			update INVENTARIOMEDCLINICA  I set cantidad = cantNueva WHERE I.rifClinica = rifClinica AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
			commit;
			transConfirm := 1;
		ELSIF array_inv(I).cantidad =  cantConsumoAux THEN
			cantNueva := array_inv(I).cantidad - cantidadConsumo;
			update INVENTARIOMEDCLINICA  I set cantidad = cantNueva, I.fechaEgreso = to_date(sysdate,'dd/mm/yyyy') WHERE I.rifClinica = rifClinica AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
			commit;
			transConfirm := 1;
		ELSIF array_inv(I).cantidad <  cantConsumoAux THEN
			cantExcedente :=  cantidadConsumo - array_inv(I).cantidad;
			update INVENTARIOMEDCLINICA  I set cantidad = 0, I.fechaEgreso = to_date(sysdate,'dd/mm/yyyy') WHERE I.rifClinica = rifClinica AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
			commit;
			cantConsumoAux := cantExcedente;
		END IF;
		EXIT WHEN transConfirm =1;
	END LOOP;
END;
---------------------------------------------------------------------------------------------------------------------------------------

CREATE OR REPLACE 
FUNCTION DescuentosXdoctor 
(ciDoctor in VARCHAR2 ) RETURN varchar2
AS
multasDescuentos varchar2(5000);
descuentos varchar2(1000);
filaDescuento varchar2(1000);
TotalMultaschar varchar2(1000);
TotalDescuentoschar varchar2(1000);
BEGIN
	
	select to_char(X.sumita) into TotalMultaschar from  (select SUM(d.monto) sumita FROM DESCUENTOMULTAEMPLEADO d WHERE d.ciDoctor = ciDoctor and d.tipo = 'M') X;

	--select to_char(X.sumita) into TotalDescuentoschar from  (select SUM(d.monto) sumita FROM DESCUENTOMULTAEMPLEADO d WHERE d.ciDoctor = ciDoctor and d.tipo = 'D') X;
	--multas := 'monto en multas generales: '||totalmultas+'';	

	FOR filaDescuento IN
	(SELECT concat(d.monto,' ',d.motivo,', ' ) FROM DESCUENTOMULTAEMPLEADO d WHERE  d.ciDoctor =ciDoctor AND d.tipo = 'D' ) LOOP
		descuentos := descuentos;
		DBMS_OUTPUT.PUT_LINE('descuentos:  '    || descuentos);
	END LOOP;

	multasDescuentos := descuentos + TotalMultaschar;

	return multasDescuentos;
--||/*||' '||filadescuento.monto||*/', '
END; -- NO FUNCION PARA EL REPORTE de sueldo actual por cedula.

---------------------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
FUNCTION verifExistMedInvAmbulatorio
(rifAmbulatorio IN VARCHAR2 ,
idMedicinas IN VARCHAR2, fechaVec DATE ) RETURN NUMBER
AS 
v_inventario         INVENTARIOMEDAMBULATORIO%ROWTYPE;
fechaVarchar varchar2(49);
type inv_tipoarray is varray(1000) of INVENTARIOMEDAMBULATORIO%ROWTYPE;
array_inv inv_tipoarray := inv_tipoarray() ;
indx   number := 1;
fechaAux DATE;
cantidadDatos number (20);
BEGIN

	fechaVarchar := to_char(fechaVec,'dd/mm/yyyy');
	--fechaAux := fechaVec;

	FOR v_inventario IN
	(SELECT i.rifAmbulatorio, i.idMedicina,i.cantidad, to_char(i.fechaVencimiento,'dd/mm/yyyy') fechaVencimiento FROM INVENTARIOMEDAMBULATORIO i WHERE
	i.rifAmbulatorio = rifAmbulatorio AND i.idMedicina = idMedicinas AND i.fechaVencimiento = fechaVarchar ) LOOP

		fechaAux := to_date(v_inventario.fechaVencimiento,'dd/mm/yyyy');
		
		if indx < array_inv.limit then
		   array_inv.extend;
		   array_inv(array_inv.last).rifAmbulatorio:= v_inventario.rifAmbulatorio;
		   array_inv(array_inv.last).idMedicina := v_inventario.idMedicina;
		   array_inv(array_inv.last).cantidad := v_inventario.cantidad;
		   array_inv(array_inv.last).fechaVencimiento := fechaAux;		
		   indx := indx +1;
		end if;

		DBMS_OUTPUT.PUT_LINE('RIF Ambulatorio:  '    || 
		array_inv(array_inv.last).rifAmbulatorio);
		DBMS_OUTPUT.PUT_LINE('idMedicina '   || 
		array_inv(array_inv.last).idMedicina);
		DBMS_OUTPUT.PUT_LINE('cantidad de medicina '   || 
		array_inv(array_inv.last).cantidad );
		DBMS_OUTPUT.PUT_LINE('fecha vence '   || 
		array_inv(array_inv.last).fechaVencimiento);

	END LOOP;
	cantidadDatos := array_inv.COUNT;
	--DBMS_OUTPUT.PUT_LINE('Cantidad: '   || cantidadDatos);
	RETURN cantidadDatos;

END;
----------------------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
PROCEDURE actualInvenAfterConsAmbulat
(rifAMBULATORIO IN VARCHAR2 ,idMedicina IN VARCHAR2 ,cantidadConsumo NUMBER) 
AS
v_inventario         INVENTARIOMEDAMBULATORIO%ROWTYPE;
type inv_tipoarray is varray(1000) of INVENTARIOMEDAMBULATORIO%rowtype;
array_inv inv_tipoarray := inv_tipoarray();
indx   number := 1;
cantidadExistencias NUMBER := 0;
cantidadMedRecord NUMBER := 0;
transConfirm NUMBER := 0;
fechaVarchar varchar2(49);
fechaAux DATE;
cantNueva NUMBER := 0;
cantExcedente NUMBER :=0;
cantConsumoAux NUMBER :=0;
BEGIN 
	cantConsumoAux := cantidadConsumo;
	/*LOOP PARA BUSCAR LAS EXISTENCIAS DE ESA MEDICINA*/
	FOR v_inventario IN
	(SELECT i.rifAMBULATORIO, i.idMedicina,i.cantidad,to_char(i.fechaVencimiento,'dd/mm/yyyy') fechaVencimiento FROM INVENTARIOMEDAMBULATORIO i WHERE
	i.rifAMBULATORIO = rifAMBULATORIO AND i.idMedicina = idMedicina AND I.fechaEgreso is null AND to_date(sysdate,'dd/mm/yyyy')< to_date(i.fechaVencimiento,'dd/mm/yyyy') ORDER BY i.fechaVencimiento ASC) LOOP

		fechaVarchar := v_inventario.fechaVencimiento;
		fechaAux := to_date(v_inventario.fechaVencimiento,'dd/mm/yyyy');
		
		if indx < array_inv.limit then
		   array_inv.extend;
		   array_inv(array_inv.last).rifAMBULATORIO := v_inventario.rifAMBULATORIO;
		   array_inv(array_inv.last).idMedicina := v_inventario.idMedicina;
		   array_inv(array_inv.last).cantidad := v_inventario.cantidad;
		   array_inv(array_inv.last).fechaVencimiento := fechaAux;	
		   indx := indx +1;
		end if;

		DBMS_OUTPUT.PUT_LINE('RIF AMBULATORIO:  '    || 
		array_inv(array_inv.last).rifAMBULATORIO);
		DBMS_OUTPUT.PUT_LINE('idMedicina '   || 
		array_inv(array_inv.last).idMedicina);
		DBMS_OUTPUT.PUT_LINE('cantidad de medicina '   || 
		array_inv(array_inv.last).cantidad );
	END LOOP; 
	cantidadExistencias := array_inv.COUNT;
	
	/*LOOP que actualiza el inventario segun el consumo*/
	FOR I in 1..array_inv.COUNT LOOP
		fechaVarchar := to_char(array_inv(I).fechaVencimiento,'dd/mm/yyyy');
		
		IF array_inv(I).cantidad >  cantConsumoAux THEN
			cantNueva := array_inv(I).cantidad - cantConsumoAux;		
			update INVENTARIOMEDAMBULATORIO  I set cantidad = cantNueva WHERE I.rifAMBULATORIO = rifAMBULATORIO AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
			commit;
			transConfirm := 1;
		ELSIF array_inv(I).cantidad =  cantConsumoAux THEN
			cantNueva := array_inv(I).cantidad - cantidadConsumo;
			update INVENTARIOMEDAMBULATORIO  I set cantidad = cantNueva, I.fechaEgreso = to_date(sysdate,'dd/mm/yyyy') WHERE I.rifAMBULATORIO = rifAMBULATORIO AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
			commit;
			transConfirm := 1;
		ELSIF array_inv(I).cantidad <  cantConsumoAux THEN
			cantExcedente :=  cantidadConsumo - array_inv(I).cantidad;
			update INVENTARIOMEDAMBULATORIO  I set cantidad = 0, I.fechaEgreso = to_date(sysdate,'dd/mm/yyyy') WHERE I.rifAMBULATORIO = rifAMBULATORIO AND I.idMedicina = idMedicina AND to_char(I.fechaVencimiento,'dd/mm/yyyy') = fechaVarchar;
			commit;
			cantConsumoAux := cantExcedente;
		END IF;
		EXIT WHEN transConfirm =1;
	END LOOP;
END;
----------------------------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE 
PROCEDURE insertarconsumomedambulatorio
(idMedicina IN NUMBER ,
rifAmbulatorio IN VARCHAR2 ,
cantidad IN NUMBER )
AS 
BEGIN   
	INSERT INTO CONSUMOMEDICINAAMBULATORIO VALUES (idMedicina,rifAmbulatorio,cantidad,to_date(SYSDATE,'dd/mm/yyyy'));
	commit;
	actualInvenAfterConsAmbulat( rifAmbulatorio,idMedicina ,cantidad);
END;
----------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------